﻿using Dapr;
using Dapr.Client;
using Microsoft.AspNetCore.Mvc;
using System.Text;

namespace FrontEnd.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class DaprStateManagementController : ControllerBase
    {
        private readonly ILogger<DaprStateManagementController> _logger;
        private readonly DaprClient _daprClient;
        public DaprStateManagementController(ILogger<DaprStateManagementController> logger, DaprClient daprClient)
        {
            _logger = logger;
            _daprClient = daprClient;
        }

        const string STATE_STORE = "statestore";
        const string KEY_NAME = "guid";

        // 强一致性保存一个值
        [HttpPost]
        public async Task<ActionResult> PostAsync()
        {
            _logger.LogInformation("Enter the PostAsync method.");
            await _daprClient.SaveStateAsync<string>(STATE_STORE, KEY_NAME, Guid.NewGuid().ToString(), new StateOptions() { Consistency = ConsistencyMode.Strong });
            return Ok("done");
        }

        // 通过ETag防止并发冲突，保存一个值(默认最后写入获胜)
        [HttpPost("withetag")]
        public async Task<ActionResult> PostWithETagAsync()
        {
            _logger.LogInformation("Enter the PostWithETagAsync method.");
            var (value, etag) = await _daprClient.GetStateAndETagAsync<string>(STATE_STORE, KEY_NAME);
            await _daprClient.TrySaveStateAsync<string>(STATE_STORE, KEY_NAME, Guid.NewGuid().ToString(), etag, new StateOptions() { Concurrency = ConcurrencyMode.FirstWrite });
            return Ok("done");
        }

        // 获取一个值
        [HttpGet]
        public async Task<ActionResult> GetAsync()
        {
            _logger.LogInformation("Enter the GetAsync method.");
            var result = await _daprClient.GetStateAsync<string>(STATE_STORE, KEY_NAME);
            return Ok(result);
        }
        // 获取一个值和ETag
        [HttpGet("withetag")]
        public async Task<ActionResult> GetWithETagAsync()
        {
            _logger.LogInformation("Enter the GetWithETagAsync method.");
            var (value, etag) = await _daprClient.GetStateAndETagAsync<string>(STATE_STORE, KEY_NAME);
            return Ok($"value is {value}, etag is {etag}");
        }


        // 删除一个值
        [HttpDelete]
        public async Task<ActionResult> DeleteAsync()
        {
            _logger.LogInformation("Enter the DeleteAsync method.");
            await _daprClient.DeleteStateAsync(STATE_STORE, KEY_NAME);
            return Ok("done");
        }
        // 通过ETag防止并发冲突，删除一个值
        [HttpDelete("withetag")]
        public async Task<ActionResult> DeleteWithETagAsync()
        {
            _logger.LogInformation("Enter the DeleteWithETagAsync method.");
            var (value, etag) = await _daprClient.GetStateAndETagAsync<string>(STATE_STORE, KEY_NAME);
            var success = await _daprClient.TryDeleteStateAsync(STATE_STORE, KEY_NAME, etag);
            return Ok($"value is {value}, etag is {etag}");
        }

        // 根据FromState获取一个值，健值name从路由模板获取
        [HttpGet("fromState/{name}")]
        public async Task<ActionResult> GetFromBindingAsync([FromState(STATE_STORE, KEY_NAME)] StateEntry<string> state)
        {
            _logger.LogInformation("Enter the GetFromBindingAsync method.");
            var myVal = await Task.FromResult(state.Value);
            return Ok(myVal);
        }


        // 根据FromState获取并修改值，健值name从路由模板获取
        [HttpPut("fromState/{name}")]
        public async Task<ActionResult> PutFromBindingAsync([FromState(STATE_STORE, KEY_NAME)] StateEntry<string> state)
        {
            _logger.LogInformation("Enter the PostWithBindingAsync method.");
            state.Value = Guid.NewGuid().ToString();
            return Ok(await state.TrySaveAsync());
        }

        // 通过事务保存和检索多个状态
        [HttpPost("list")]
        public async Task<ActionResult> PostListAsync() 
        {
            var list = new List<StateTransactionRequest>()
            {
                new StateTransactionRequest("test1", Encoding.UTF8.GetBytes("value1"), StateOperationType.Upsert),
                new StateTransactionRequest("test2", Encoding.UTF8.GetBytes("value2"), StateOperationType.Upsert),
            };
            await _daprClient.ExecuteStateTransactionAsync(STATE_STORE, list);

            var datas = await _daprClient.GetBulkStateAsync(STATE_STORE, list.Select(r => r.Key).ToList(), 0);
            return Ok($"Got items: {string.Join(",", datas.Select(d => $"{d.Key}={d.Value}"))}");
        }


        // 获取多个个值
        [HttpGet("list")]
        public async Task<ActionResult> GetListAsync()
        {
            _logger.LogInformation("Enter the GetListAsync method.");
            var result = await _daprClient.GetBulkStateAsync(STATE_STORE, new List<string> { KEY_NAME }, 10);
            return Ok(result);
        }

        // 删除多个个值
        [HttpDelete("list")]
        public async Task<ActionResult> DeleteListAsync()
        {
            _logger.LogInformation("Enter the DeleteListAsync method.");
            var data = await _daprClient.GetBulkStateAsync(STATE_STORE, new List<string> { KEY_NAME }, 10);
            var removeList = new List<BulkDeleteStateItem>();
            foreach (var item in data)
            {
                removeList.Add(new BulkDeleteStateItem(item.Key, item.ETag));
            }
            await _daprClient.DeleteBulkStateAsync(STATE_STORE, removeList);
            return Ok("done");
        }

    }
}
